package gov.dhs.cis.soa.readers.reqpro;

import gov.dhs.cis.soa.Constants;
import gov.dhs.cis.soa.SOAData;
import gov.dhs.cis.soa.Utils;
import gov.dhs.cis.soa.data.UseCase;

import java.util.ArrayList;
import java.util.Enumeration;

import org.apache.log4j.Logger;

import com.rational.reqpro.rpx.Application;
import com.rational.reqpro.rpx.AttrValue;
import com.rational.reqpro.rpx._Application;
import com.rational.reqpro.rpx._AttrValues;
import com.rational.reqpro.rpx._Errors;
import com.rational.reqpro.rpx._Project;
import com.rational.reqpro.rpx._Requirement;
import com.rational.reqpro.rpx._Requirements;
import com.rational.reqpro.rpx.enumOpenProjectOptions;
import com.rational.reqpro.rpx.enumProjectFlags;
import com.rational.reqpro.rpx.enumRelatedProjectOptions;
import com.rational.reqpro.rpx.enumRequirementFlags;
import com.rational.reqpro.rpx.enumRequirementLookups;
import com.rational.reqpro.rpx.enumRequirementsWeights;
import com.rational.reqpro.rpx.enumTagFormat;
import com.rational.rjcb.ComObjectProxy;

public class UseCasesReader {
	static final Logger loger = Logger.getLogger(UseCasesReader.class);

	public SOAData extractUseCases(SOAData soaData) {
		_Application RPX = null;
		try {
			RPX = new Application();
			_Project project = RPX.OpenProject(Constants.REQPRO_PROJECT,
					enumOpenProjectOptions.eOpenProjOpt_RQSFile, Constants.REQPRO_USER,
					Constants.REQPRO_PASS, enumProjectFlags.eProjFlag_Normal,
					enumRelatedProjectOptions.eRelatedProjOption_ConnectNone);
			int ucCount = 0;
			ArrayList<UseCase> useCaseList = new ArrayList<UseCase>();
			soaData.useCaseList = useCaseList;
			String[] reqTypes = new String[] {"UC", "SERV" };
			
			for(String reqType : reqTypes) {
			_Requirements requs = project.GetRequirements(reqType, enumRequirementLookups.eReqLookup_Tag, 
					enumRequirementsWeights.eReqWeight_Medium, enumRequirementFlags.eReqFlag_Empty,
					100, 40);
			int reqCount = requs.getCount();
			System.out.println("Req Count : " + reqCount);
			if(reqCount > 0) {
				requs.MoveFirst();
				_Requirement req = null;
				for(int i = 0; i < reqCount; i++) {
					req = requs.GetCurrentRequirement();
					if(req.getLevel() == 0) {
						ucCount++;
						useCaseList.add(readRequirement(req));
					}
					requs.MoveNext();
				}
			}
			}
			System.out.println("Total UC count : " + ucCount);
			
			project.CloseProject();
			ComObjectProxy obj = (ComObjectProxy) RPX;
			obj.release();
			RPX= null;			
		} catch (Exception e) {
			try {
				_Errors err = RPX.getErrors();
				System.out.println(err.getAllMessages());
				e.printStackTrace();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}				
		} finally {
		}
		return soaData;
	}

	private UseCase getRequirementAttrs(UseCase u, _Requirement req) throws Exception {
		_AttrValues types = req.getAttrValues();
		int count = types.getCount();
		if(count <= 0)
			return u;
		//System.out.println("RequirementAttrs# :" + count);
		Enumeration e = types.NewEnum();
		while(e.hasMoreElements()) {
			AttrValue type = new AttrValue(e.nextElement());
			//System.out.println(type.getLabel() + " : " + type.getText());
			if("Management Function".equalsIgnoreCase(type.getLabel())) {
				u.wipt = type.getText();
			} else if("Increment 1 Identifier".equalsIgnoreCase(type.getLabel())) {
				u.unumber = type.getText();
			} else if("Planned First Release".equalsIgnoreCase(type.getLabel())) {
				u.release = type.getText();
			} else if("Service Definition".equalsIgnoreCase(type.getLabel())) {
				u.stereotype = ("Yes".equalsIgnoreCase(type.getText()) ? "SD" : "UC");
			} else if("L3 Process".equalsIgnoreCase(type.getLabel())) {
				u.busProcessName = type.getText();
			} else if("Working Status".equalsIgnoreCase(type.getLabel())) {
				u.status = 	type.getText();
				u.modSiceIRR = type.getText();
			}
		}
		if("SERV".equalsIgnoreCase(req.getReqType().getReqPrefix()))
			u.stereotype = "SERV";
		return u;
	}


	public UseCase readRequirement(_Requirement req) throws Exception {
		UseCase u = new UseCase();
		u.id = Utils.getNextId();
		u.uname = req.getName();
		u.descText = req.getText();
		u.reqprodbid = req.getTag(enumTagFormat.eTagFormat_FullTag);
		
		//System.out.println(req.getName() + " : " + req.getText());
		//System.out.println(req.getTag(enumTagFormat.eTagFormat_FullTag) + ": " + req.getName());
		getRequirementAttrs(u, req);
		
		//if(Utils.isEmpty(u.unumber)) - always assign Reqpro unique#s - RSingh 10/13/2010
			u.unumber = req.getTag(enumTagFormat.eTagFormat_FullTag);

		u.createDescription();
		return u;
	}	
	
	public void printUseCases(SOAData soaData) {
		ArrayList<UseCase> useCaseList = (ArrayList<UseCase>) soaData.useCaseList;
		for(UseCase u : useCaseList) {
			//System.out.println(u.reqprodbid + "," + u.unumber + "," + u.uname + "," + u.status + "," + u.descText + "," + u.wipt + "," + u.release + "," + u.busProcessName );
			System.out.println(u.reqprodbid + "," + u.unumber + "," + u.uname + "," + u.status + "," + u.wipt + "," + u.release + "," + u.busProcessName );
		}
	}
	
	/**may be dev 
	 * @param args
	 */
	public static void main(String[] args) {
		UseCasesReader pr = new UseCasesReader();
		try {
			SOAData sData = new SOAData();
			pr.extractUseCases(sData);
			pr.printUseCases(sData);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
